#!/bin/bash
################################################################################
# File name:
#   aes100_install.sh
#
# Description:
#   This script is used for installing of aes100 A1,A2. 
#   User can use ./aes100_install.sh <UNIT_LIST> [EXTRA_CMD] to start install.
#
# Parameter:
#   1. Enter the number of the module that will be installed.
#       Example:    "1-3,5,15-18 means unit 1,2,3,5,15,16,17,18"  
#   2. Type of install. 
#       cover:      recover the installation sd_maker_1-24 folder
#       ip:         Only set ip addresses of each module after installation.
#
# Dependent file:
#   atlas_con.sh
#   atlas_emmc_icp.sh
#   altas_reset.sh
#   make_sd_card.py
#   minirc.dfl
# 
# The IP addresses of atlas modules are mapped in machine as following, 
# the X address is in parentheses:
# Module 1(i7-8850H):
# |21(1)|22(2)|23(3)|24(4)|  192.168.105.X   tty9
# |17(1)|18(2)|19(3)|20(4)|  192.168.104.X   tty8
# |13(1)|14(2)|15(3)|16(4)|  192.168.103.X   tty7
# |09(1)|10(2)|11(3)|12(4)|  192.168.109.X   tty6
# |05(1)|06(2)|07(3)|08(4)|  192.168.108.X   tty5
# |01(1)|02(2)|03(3)|04(4)|  192.168.107.X   tty4
# Module 1(i3-8100H) (i5-8400H):
# |21(1)|22(2)|23(3)|24(4)|  192.168.103.X   tty9
# |17(1)|18(2)|19(3)|20(4)|  192.168.102.X   tty8
# |13(1)|14(2)|15(3)|16(4)|  192.168.101.X   tty7
# |09(1)|10(2)|11(3)|12(4)|  192.168.107.X   tty6
# |05(1)|06(2)|07(3)|08(4)|  192.168.106.X   tty5
# |01(1)|02(2)|03(3)|04(4)|  192.168.105.X   tty4 
# Module 2:(Atom(TM) E3950)
# |13(1)|14(2)|15(3)|16(4)|  192.168.107.X   tty7
# |09(1)|10(2)|11(3)|12(4)|  192.168.106.X   tty6
# |05(1)|06(2)|07(3)|08(4)|  192.168.105.X   tty5
# |01(1)|02(2)|03(3)|04(4)|  192.168.102.X   tty4
# Module 3:(Hygon))
# |13(1)|14(2)|15(3)|16(4)|  192.168.102.X   tty6
# |09(1)|10(2)|11(3)|12(4)|  192.168.107.X   tty4
# |05(1)|06(2)|07(3)|08(4)|  192.168.106.X   tty3
# |01(1)|02(2)|03(3)|04(4)|  192.168.105.X   tty2
 
################################################################################
set +x

SCRIPTS_PATH="$( cd "$(dirname "$0")" ; pwd -P )""/"
LOGIN_NAME="HwHiAiUser"
USER_PSWD="Huawei2012#"
ROOT_PSWD="Huawei12#$"
RESULT=${SCRIPTS_PATH}/result.log
CPU_MODE_I3="i3"
CPU_MODE_I7="i7"
CPU_MODE_HYGON="C86"
CPU_MODE_ATOM="ATOM"
rm -fr /root/.ssh/known_hosts
rm -fr result.log

unit=$1
run_type=$2 

# Install and check necessary tools 
TOOLS=(qemu-user-static binfmt-support gcc-aarch64-linux-gnu \
g++-aarch64-linux-gnu expect cpio gzip i2c-tools minicom netplan.io \
vim net-tools openssh-server)

length=${#TOOLS[@]}
sudo apt-get update
for (( i=0;i<$length;i++ ))
do
    ret=$(dpkg -l | awk '($2=="${TOOLS[$i]}")') 
    if [[ x"$ret" == x"" ]]; then
        echo "[INFO] ${TOOLS[$i]} need to be installed"
        
        sudo apt-get -y install ${TOOLS[$i]}
        ret=$?
        if [[ $ret != 0 ]]; then     
            echo "install ${TOOLS[$i]} failed"
            exit 1
        fi
    fi
done
echo "Check tools finished."

# Check type of COMe
A2_PCIE_SWITCH=$(lspci | grep "ASMedia Technology" | awk '{print $8}' \
                 | awk 'NR==1')
CPU_TYPE=$(lscpu | grep "Model name" | awk '{print $4}')
CPU_MODEL_NUM=$(lscpu | grep "Model name" | awk '{print $5}')
COME_NO_VGA=$(lspci | grep "Pericom Semiconductor" | awk '{print $7}' \
              | awk 'NR==1')
if [[ ${A2_PCIE_SWITCH} == "2806" ]]; then
    if [[ ${CPU_TYPE} == "Core(TM)" ]]; then
        if [[ ${CPU_MODEL_NUM} == "i7-8850H" ]]; then 
            core_num=24
            bus_num_a2=(1 2 3 a b c)
            bus_count=6
            for (( i=0; i<3; i++ ))
            do
                # Add compensation to adjust pci bus number as A1
                bus_num[$i]=$(( ${bus_num_a2[$i]} + 2 ))
            done
            # The convertion of number system for pci bus number
            for (( i=3; i<$bus_count; i++ ))
            do
                # Add compensation to adjust bus number as A1
                bus_num[$i]=$(( $((16#${bus_num_a2[$i]})) - 3 ))
            done            
            mod_flag=${CPU_MODE_I7}
        # The PCI bus number of i3 or i5
        elif [[ ${CPU_MODEL_NUM} == "i3-8100H" ]] || \
             [[ ${CPU_MODEL_NUM} == "i5-8400H" ]]; then
            core_num=24
            bus_num_a2=(1 2 3 a b c)
            bus_count=6
            for (( i=0; i<3; i++ ))
            do
                bus_num[$i]=${bus_num_a2[$i]}
            done
            # The convertion of number system for pci bus number
            for (( i=3; i<$bus_count; i++ ))
            do
                # Add compensation to adjust pci bus number as A1
                bus_num[$i]=$(( $((16#${bus_num_a2[$i]})) - 5 ))
            done
            mod_flag=${CPU_MODE_I3}
        fi
    elif [[ ${CPU_TYPE} == "Atom(TM)" ]]; then
        # E3950 with VGA or without VGA
        if [[ ${COME_NO_VGA} == "2404" ]]; then
            core_num=16
            bus_num_a2=(7 a b c) 
            bus_count=4
            # The convertion of number system for pci bus number
            for (( i=0; i<$bus_count; i++ ))
            do
                # Add compensation to adjust pci bus number as A1
                bus_num[$i]=$(( $((16#${bus_num_a2[$i]})) - 5 ))
            done
            mod_flag=${CPU_MODE_ATOM}
        fi
   elif [[ ${CPU_TYPE} == "C86" ]]; then
	if [[ ${CPU_MODEL_NUM} == "3250" ]]; then
            core_num=16
            bus_num_a2=(a b c 1) 
            bus_count=4
            for (( i=0; i<3; i++ ))
            do
                # Add compensation to adjust pci bus number as A1
                bus_num[$i]=$(( $((16#${bus_num_a2[$i]})) - 5 ))
            done
	    # The convertion of number system for pci bus number
            for (( i=3; i<$bus_count; i++ ))
            do
                # Add compensation to adjust pci bus number as A1
                bus_num[$i]=$(( ${bus_num_a2[$i]} + 1 ))
            done
            mod_flag=${CPU_MODE_HYGON}

        fi
    else
        echo "Incorrect CPU type"
        exit 2
    fi
else
    if [[ ${CPU_TYPE} == "Core(TM)" ]]; then
        if [[ ${CPU_MODEL_NUM} == "i7-8850H" ]]; then 
            core_num=24
            bus_num=(3 4 5 7 8 9)
            bus_count=6
            mod_flag=${CPU_MODE_I7}
        # The PCI bus number of i3 or i5
        elif [[ ${CPU_MODEL_NUM} == "i3-8100H" ]] || \
             [[ ${CPU_MODEL_NUM} == "i5-8400H" ]]; then
            core_num=24
            bus_num=(1 2 3 5 6 7)
            bus_count=6
            mod_flag=${CPU_MODE_I3}
        fi
    elif [[ ${CPU_TYPE} == "Atom(TM)" ]]; then
        # E3950 with VGA or without VGA
        if [[ ${COME_NO_VGA} == "2404" ]]; then
            core_num=16
            bus_num=(2 5 6 7) 
            bus_count=4
        fi
    else
        echo "Incorrect CPU type"
        exit 2
    fi
fi

# Read Ethernet name
eth=()
if [[ ${A2_PCIE_SWITCH} == "2806" ]]; then
    for i in ${bus_num_a2[@]}
    do
        val=$(ls /sys/bus/pci/devices/0000:0${i}:00.0/net)
        eth=( "${eth[@]}" "$val" )
    done
else
    for i in ${bus_num[@]}
    do
        val=$(ls /sys/bus/pci/devices/0000:0${i}:00.0/net)
        eth=( "${eth[@]}" "$val" )
    done
fi

# Check type of parameter
if [[ x"$unit"  == x"" ]] || [[ $unit  == "all" ]]; then
    unit="1-$core_num"
fi
echo $unit

# Check user input parameter
array=(${unit//,/ })
re="[1-9][0-9]{0,}-[1-9][0-9]{0,}"
count=0
new_arr=''

for var in ${array[@]}
do
    # delete '-'; example 2-9
    if [[ "$var" =~ $re ]]; then
        unset array[$count]
        num=(${var//-/ })
        result=$(( ${num[1]} - ${num[0]} ))
        
        #input data for x-y
        for (( i=0;i<=$result;i++ ))
        do
            app_arr[$(( $i ))]=$(( ${num[0]} + $i ))
        done

        new_arr=( "${new_arr[@]}" "${app_arr[@]}" )

    # check number
    elif [ -n "`echo $var | sed 's/[0-9]//g'`" ]; then
        echo "Plesase input Parameter 1-$core_num"
        exit 1
    else
        new_arr=( "${new_arr[@]}" "$var" )
    fi

    unset app_arr
    let count++
done 

# Check parameter in compliance
arr=("${new_arr[@]}")
sort_arr=$(echo  ${arr[@]} | tr ' ' '\n' | sort -n | uniq )
sort_arr_to_str=$(echo  ${sort_arr[@]} | sed 's/ //g')
unsort_arr_to_str=$(echo  ${arr[@]} | sed 's/ //g')

if [[ ${sort_arr_to_str} -ne ${unsort_arr_to_str} ]]; then
    echo ${sort_arr_to_str}
    echo ${unsort_arr_to_str}
    echo "Wrong Parameter"
    exit 1
fi

for var in ${sort_arr[@]}
do
    if (( $var < 1 || $var > $core_num )); then
        echo "Plesase input Parameter 1-$core_num"
        exit 1
    fi
done
echo ${sort_arr[@]}

# Get enp, serial, tty and ip from module number
function module_number_convert()
{
    # module number
    module_num=$1 
    # feedback parameter
    type=$2
   
    if [[ $core_num == 16 ]] && [[ $mod_flag == ${CPU_MODE_HYGON} ]]; then
        if [[ $module_num -ge 1 ]] && [[ $module_num -le 4 ]]; then
            seri_num=$(( ${i} ))
            tty="ttyS4"
            pci_num=${bus_num[0]}
            netbus=${eth[0]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 5 ]] && [[ $module_num -le 8 ]]; then
            seri_num=$(( ${i} - 4 ))
            tty="ttyS5"
            pci_num=${bus_num[1]}
            netbus=${eth[1]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 9 ]] && [[ $module_num -le 12 ]]; then
            seri_num=$(( ${i} - 8 ))
            tty="ttyS6"
            pci_num=${bus_num[2]}
            netbus=${eth[2]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 13 ]] && [[ $module_num -le 16 ]]; then
            seri_num=$(( ${i} - 12 ))
            tty="ttyS7"
            pci_num=${bus_num[3]}
            netbus=${eth[3]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        fi
    fi
    
    if [[ $core_num == 16 ]] && [[ $mod_flag == ${CPU_MODE_HYGON} ]]; then
        if [[ $module_num -ge 1 ]] && [[ $module_num -le 4 ]]; then
            seri_num=$(( ${i} ))
            tty="ttyS2"
            pci_num=${bus_num[0]}
            netbus=${eth[0]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 5 ]] && [[ $module_num -le 8 ]]; then
            seri_num=$(( ${i} - 4 ))
            tty="ttyS3"
            pci_num=${bus_num[1]}
            netbus=${eth[1]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 9 ]] && [[ $module_num -le 12 ]]; then
            seri_num=$(( ${i} - 8 ))
            tty="ttyS4"
            pci_num=${bus_num[2]}
            netbus=${eth[2]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 13 ]] && [[ $module_num -le 16 ]]; then
            seri_num=$(( ${i} - 12 ))
            tty="ttyS6"
            pci_num=${bus_num[3]}
            netbus=${eth[3]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        fi
    fi

    if [[ $core_num == 24 ]] && [[ $mod_flag == ${CPU_MODE_I7} ]]; then
        if [[ $module_num -ge 1 ]] && [[ $module_num -le 4 ]]; then
            seri_num=$(( ${i} ))
            tty="ttyS4"
            pci_num=${bus_num[3]}
            netbus=${eth[3]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 5 ]] && [[ $module_num -le 8 ]]; then
            seri_num=$(( ${i} - 4 ))
            tty="ttyS5"
            pci_num=${bus_num[4]}
            netbus=${eth[4]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 9 ]] && [[ $module_num -le 12 ]]; then
            seri_num=$(( ${i} - 8 ))
            tty="ttyS6"
            pci_num=${bus_num[5]}
            netbus=${eth[5]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 13 ]] && [[ $module_num -le 16 ]]; then
            seri_num=$(( ${i} - 12 ))
            tty="ttyS7"
            pci_num=${bus_num[0]}
            netbus=${eth[0]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 17 ]] && [[ $module_num -le 20 ]]; then
            seri_num=$(( ${i} - 16 ))
            tty="ttyS8"
            pci_num=${bus_num[1]}
            netbus=${eth[1]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 21 ]] && [[ $module_num -le 24 ]]; then
            seri_num=$(( ${i} - 20 ))
            tty="ttyS9"
            pci_num=${bus_num[2]}
            netbus=${eth[2]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        fi
    elif [[ $core_num == 24 ]] && [[ $mod_flag == ${CPU_MODE_I3} ]];then
        if [[ $module_num -ge 1 ]] && [[ $module_num -le 4 ]]; then
            seri_num=$(( ${i} ))
            tty="ttyS4"
            pci_num=${bus_num[3]}
            netbus=${eth[3]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 5 ]] && [[ $module_num -le 8 ]]; then
            seri_num=$(( ${i} - 4 ))
            tty="ttyS5"
            pci_num=${bus_num[4]}
            netbus=${eth[4]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 9 ]] && [[ $module_num -le 12 ]]; then
            seri_num=$(( ${i} - 8 ))
            tty="ttyS6"
            pci_num=${bus_num[5]}
            netbus=${eth[5]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 13 ]] && [[ $module_num -le 16 ]]; then
            seri_num=$(( ${i} - 12 ))
            tty="ttyS7"
            pci_num=${bus_num[0]}
            netbus=${eth[0]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 17 ]] && [[ $module_num -le 20 ]]; then
            seri_num=$(( ${i} - 16 ))
            tty="ttyS8"
            pci_num=${bus_num[1]}
            netbus=${eth[1]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        elif [[ $module_num -ge 21 ]] && [[ $module_num -le 24 ]]; then
            seri_num=$(( ${i} - 20 ))
            tty="ttyS9"
            pci_num=${bus_num[2]}
            netbus=${eth[2]}
            new_ip="192.168.10${pci_num}.${seri_num}"
        fi    
    fi

    if [[ $type == "seri_num" ]]; then
        ret=$seri_num
    elif [[ $type == "tty" ]]; then
        ret=$tty
    elif [[ $type == "pci_num" ]]; then
        ret=$pci_num
    elif [[ $type == "new_ip" ]]; then
        ret=$new_ip
    elif [[ $type == "eth" ]]; then
        ret=$netbus  
    fi
}

# Check enp number
arr_enp_old=""
for i in ${sort_arr[@]}
do
    module_number_convert $i pci_num
    arr_enp_old=( "${arr_enp_old[@]}" $ret )
done

arr_enp=$(echo ${arr_enp_old[@]} | tr ' ' '\n' | sort -n | uniq)

#check serial number
arr_seri_old=""
for i in ${sort_arr[@]}
do
    module_number_convert $i seri_num
    arr_seri_old=( "${arr_seri_old[@]}" $ret )
done

arr_seri=$(echo ${arr_seri_old[@]} | tr ' ' '\n' | sort -n | uniq)

# Get number of modules
module_count=0
for i in ${sort_arr[@]}
do
    let module_count++
done

# check sd_maker folder
cd ../..
for i in ${sort_arr[@]}
do
    if [[ x"$run_type" == x"cover" ]]; then
        cp -fr sd_maker/* sd_maker_${i}/
        echo "copy sd_make_${i}"
    fi

    if [[ ! -d sd_maker_${i} ]]; then
        mkdir -p sd_maker_${i}
        cp -fr sd_maker/* sd_maker_${i}/
        echo "copy sd_make_${i}"
    fi
done
cd -

# Close netplan-manager service and set ip
sudo systemctl stop NetworkManager
sudo systemctl disable NetworkManager
sudo systemctl mask NetworkManager

netplan apply
sleep 5s

for (( i=0; i<$bus_count; i++ ))
do
    ifconfig ${eth[$i]}:0 192.168.10${bus_num[$i]}.100 up
    sleep 1s
done

################################################################################
echo "Start to install all atlas"
echo "Disconnect all modules"

# Disconnect and restart all Atlas modules
function set_start_emmc_ip()
{
    for i in ${sort_arr[@]} 
    do
        rm -fr /root/.ssh/known_hosts
        bash ${SCRIPTS_PATH}/atlas_emmc_icp.sh ${i} disconnect
        bash ${SCRIPTS_PATH}/atlas_reset.sh ${i}
        echo "${i} disconnect"
    done
}

# SSH Connect and modify ip
function set_ip()
{
    origin_ip="192.168.0.2"
    ip=$1
    /usr/bin/expect<<-EOF
    set timeout 60
    spawn ssh -o GSSAPIAuthentication=no ${origin_ip} -l ${LOGIN_NAME} -p 22

    expect {
        "(yes/no*" {send "yes\r";exp_continue}
        "*assword:" {send "${USER_PSWD}\r"}
    }
    set timeout 1
    expect "*\$"
    send "su -\r"
    expect "*assword:"
    send "${ROOT_PSWD}\r"
    expect "*#"
    send "ifconfig eth0 ${ip}\r"

    expect eof
EOF
}

# Check ip
function check_ip()
{
    ip=$1
    num=1

    while [ $num -lt 30 ]  
    do
        if ping -c 1 $ip >/dev/null; then
            echo "${ip} Ping is success" | tee -a result.log
            return 0
        else	   
            let num++
        fi
    done
    return 1
}

# Get module number from enp number and serial number 
function model_num()
{
    #enp enp3s0-enp9s0 i7-8850H
    #enp enp1s0-enp7s0 i3-8100H
    nep_num=$1
    #serial number :1 2 3 4
    serial_num=$2 

    if [[ $core_num == 8 ]]; then
        case ${nep_num} in
        2)
            mode_num=$(( (${nep_num} - 1) * 12 + ${serial_num} ))
            ;;
        5)
            ;&
        6)
            ;&
        7)
            mode_num=$(( (${nep_num} - 5) * 4 + ${serial_num} ))
            ;;
        *)
            echo "wrong"
            ;;
        esac
    fi

    if [[ $core_num == 16 ]]; then
        case ${nep_num} in
        2)
            mode_num=$(( (${nep_num} - 2) * 4 + ${serial_num} ))
            ;;
        5)
            ;&
        6)
            ;&
        7)
            mode_num=$(( (${nep_num} - 4) * 4 + ${serial_num} ))
            ;;
        *)
            echo "wrong"
            ;;
        esac
    fi

    if [[ $core_num == 24 ]] && [[ $mod_flag == ${CPU_MODE_I7} ]]; then
        case ${nep_num} in
        3)
            ;&
        4)
            ;&
        5)
            mode_num=$(( ${nep_num} * 4 + ${serial_num} ))
            ;;
        7)
            ;&
        8)
            ;&
        9)
            mode_num=$(( (${nep_num} - 7) * 4 + ${serial_num} ))
            ;;
        *)
            echo "wrong"
            ;;
        esac
    elif [[ $core_num == 24 ]] && [[ $mod_flag == ${CPU_MODE_I3} ]]; then
        case ${nep_num} in
        1)
            ;&
        2)
            ;&
        3)
            mode_num=$(( ${nep_num} * 4 + 8 + ${serial_num} ))
            ;;
        5)
            ;&
        6)
            ;&
        7)
            mode_num=$(( (${nep_num} - 5) * 4 + ${serial_num} ))
            ;;
        *)
            echo "wrong"
            ;;
        esac    
    fi

    return ${mode_num}
}

# Start to modify ip
function atlas_set_ip()
{
    for i in ${arr_seri[@]}
    do
        #change to emmc mode and restart
        for j in ${arr_enp[@]}
        do
            # judge the number of atlas input by user
            for k in ${sort_arr[@]}
            do  
                model_num $j $i
                ret=$?

                if [[ "$ret" == "$k" ]]; then
                    echo "Set ${ret} ip"
                    echo "${ret} connect"
                    bash ${SCRIPTS_PATH}/atlas_emmc_icp.sh ${ret} connect
                    sleep 1s
                    echo "${ret} reset"
                    bash ${SCRIPTS_PATH}/atlas_reset.sh ${ret} 
                    sleep 5s 
	            fi
            done
        done

        echo "wait 1m"
        sleep 1m

        #set ip
        for j in ${arr_enp[@]}
        do
            for k in ${sort_arr[@]}
            do
                model_num $j $i
                ret=$?
                if [[ "$ret" == "$k" ]]; then
                    rm -fr /root/.ssh/known_hosts
                    model_num $j $i
                    module_number_convert $ret eth
                    eth_num=$ret
                    ifconfig ${eth_num}:1 192.168.0.100 up
                    echo "Set ${eth_num} ip"
                    check_ip 192.168.0.2
                    set_ip 192.168.10${j}.${i}
                    ifconfig ${eth_num}:1 down
                    sleep 2s
                fi
            done
        done
    done
}


# check new ip
function check_ip_aes()
{
    for (( i=0; i<$bus_count; i++ ))
    do
        ifconfig ${eth[$i]}:0 192.168.10${bus_num[$i]}.100 up
        sleep 1s
    done

    for i in ${sort_arr[@]}
    do
        rm -fr ~/.ssh/known_hosts

        module_number_convert $i pci_num
        pci_ret=$pci_num
        module_number_convert $i seri_num
        check_ip 192.168.10${pci_ret}.${ret}
    done

    sleep 1s
}

################################################################################
# Start to install emmc
function emmc_install()
{
    for i in ${sort_arr[@]}
    do
    {
        echo "Start to install ${i}"
        module_number_convert $i pci_num
        pci_ret=$ret

        module_number_convert $i seri_num
        seri_num=$ret

        cd ../../sd_maker_${i}/
        python3 make_sd_card.py recover_aes100 \
        192.168.10${pci_ret}.${seri_num}
        cd -
    }&
    done

    wait
}

# Check installed modules
function check_emmc_install()
{
    echo "Check install."
    count=0

    if [[ ! -f  ".install_result.log" ]]; then
        touch .install_result.log
    fi

    while [[ ${count} -lt ${module_count} ]]
    do
        #reset after search
        count=0
        echo "" > .install_result.log
        for i in ${sort_arr[@]}
        do
            install_result=$(cat ../../sd_maker_${i}/sd_card_making_log/make_os_sd.result 2>&1)
            if [[ $install_result == "Success" ]]; then
                let count++
                echo "Module ${i} Success" >> .install_result.log
                succ_arr=( "${succ_arr[@]}" "$i" )
            elif [[ $install_result == "Failed" ]]; then
                let count++
                echo "Module ${i} Failed" >> .install_result.log
            fi
        done
        sleep 5s
    done

    sleep 5s
    cat .install_result.log >> result.log
    rm -f .install_result.log
    cat result.log
}

# Restart modules
function restart_atlas()
{
    for i in ${sort_arr[@]}
    do
        bash ${SCRIPTS_PATH}/atlas_emmc_icp.sh ${i} disconnect
        bash ${SCRIPTS_PATH}/atlas_reset.sh ${i}
        echo "${i} disconnect"
    done
}

################################################################################
# Wait for install modules and change ip
function set_ip_davinci()
{
    cp -fr minirc.aes /etc/minicom/minirc.aes
    sleep 15s

    count=0
    for i in ${sort_arr[@]}
    do  
        #wait for other module
        let count++
        if [[ $count == 2 ]]; then
            echo "Wait 5 min for other Modules installation"
            if [[ x"$run_type" != x"ip" ]]; then
                sleep 5m
            fi
        fi

        # delete minicom lock
        echo "${i} tty connect"
        rm -fr /var/lock/LCK..*
        sleep 2s

        # connect the atlas
        bash ${SCRIPTS_PATH}/atlas_reset.sh ${i}
        bash ${SCRIPTS_PATH}/atlas_con.sh ${i}
        sleep 5s
        echo "Set ip for ${i}"

        module_number_convert $i tty

        # set the serial port channel for minicom
        tty_serial="s/ttyS[0-9]/${ret}/g"
        sed -i ${tty_serial} /etc/minicom/minirc.aes

        module_number_convert $i new_ip

        /usr/bin/expect<<-EOF
        set timeout -1
        spawn minicom aes
        while 1 {
            send "\r"
            expect {
                "davinci-mini login:" break
            }
        }

        send "\r"

        expect {
            "davinci-mini login:" {send "HwHiAiUser\r";exp_continue}
            "*assword" {send "Mind@123\r";exp_continue}
            "*r@davinci" {send "sudo su\r";}
            send "\r"
        }
        expect "root@"
        send "sed -i 's/192.168.10.2/${ret}/g' /etc/netplan/01-netcfg.yaml\r"
        expect "root@"
        send "netplan apply\r"
        expect "root@"
        sleep 1
        send "ifconfig\r"
        expect "root@"
        send "\01"  
        send "z"
        send "x"
        send "\r"
        set timeout 1
        send "\r"
        expect eof
EOF
    done
}

# Open service Network Manager
function open_network()
{
    sudo systemctl unmask NetworkManager
    sudo systemctl enable NetworkManager
    sudo systemctl start NetworkManager
}

# Set the minicom default value
function set_minicom()
{
    cp -fr minirc.dfl /etc/minicom/minirc.dfl
}

################################################################################
#main
# Only set system ip 
if [[ x"$run_type" == x"ip" ]]; then
    restart_atlas
    set_ip_davinci
    check_ip_aes
    open_network
    exit 0
fi

set_start_emmc_ip
atlas_set_ip
check_ip_aes
emmc_install
check_emmc_install
restart_atlas
set_ip_davinci
check_ip_aes
open_network
set_minicom

exit 0
